package com.esayread.utils

import android.content.Context
import android.util.Log
import com.esayread.data.Book
import com.esayread.utils.FileFormatConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.*

class BookManager(private val context: Context) {
    
    private val pathManager = BookPathManager(context)
    private val coverExtractor = CoverExtractor(context)
    
    companion object {
        private const val BOOKS_DIR = "books"
    }
    
    /**
     * 获取应用内部books目录
     */
    private fun getBooksDirectory(): File {
        val booksDir = File(context.filesDir, BOOKS_DIR)
        if (!booksDir.exists()) {
            booksDir.mkdirs()
            Log.d("BookManager", "Created books directory: ${booksDir.absolutePath}")
        }
        return booksDir
    }
    
    /**
     * 获取已存在的书籍列表
     */
    suspend fun getExistingBooks(): List<Book> = withContext(Dispatchers.IO) {
        val books = mutableListOf<Book>()
        val booksDir = getBooksDirectory()
        
        try {
            booksDir.listFiles()?.forEach { file ->
                if (file.isFile && isSupportedFile(file)) {
                    val book = createBookFromFile(file)
                    books.add(book)
                }
            }
        } catch (e: Exception) {
            Log.e("BookManager", "Error loading existing books", e)
        }
        
        Log.d("BookManager", "Found ${books.size} existing books")
        books
    }
    
    /**
     * 过滤掉已存在的书籍
     */
    suspend fun filterNewBooks(scannedBooks: List<Book>): List<Book> = withContext(Dispatchers.IO) {
        val existingBooks = getExistingBooks()
        val existingHashes = existingBooks.map { getFileHash(File(it.filePath)) }.toSet()
        
        val newBooks = scannedBooks.filter { book ->
            val hash = getFileHash(File(book.filePath))
            !existingHashes.contains(hash)
        }
        
        Log.d("BookManager", "Filtered ${scannedBooks.size} scanned books to ${newBooks.size} new books")
        newBooks
    }
    
    /**
     * 复制选中的书籍到应用内部目录
     */
    suspend fun copyBooksToLibrary(books: List<Book>): List<Book> = withContext(Dispatchers.IO) {
        val copiedBooks = mutableListOf<Book>()
        val booksDir = getBooksDirectory()
        
        books.forEach { book ->
            try {
                val sourceFile = File(book.filePath)
                if (!sourceFile.exists()) {
                    Log.w("BookManager", "Source file not found: ${book.filePath}")
                    return@forEach
                }
                
                // 生成唯一的文件名
                val fileName = generateUniqueFileName(sourceFile.name, booksDir)
                val targetFile = File(booksDir, fileName)
                
                // 复制文件
                copyFile(sourceFile, targetFile)
                
                // 创建新的Book对象，使用复制后的文件路径
                val copiedBook = book.copy(
                    id = UUID.randomUUID().toString(),
                    filePath = targetFile.absolutePath,
                    addTime = System.currentTimeMillis()
                )
                
                // 记录原始路径
                pathManager.recordBookPath(copiedBook.id, book.filePath)
                
                copiedBooks.add(copiedBook)
                Log.d("BookManager", "Successfully copied book: ${book.title} to ${targetFile.absolutePath}")
                Log.d("BookManager", "Recorded original path: ${book.filePath} for book ID: ${copiedBook.id}")
                
            } catch (e: Exception) {
                Log.e("BookManager", "Error copying book: ${book.title}", e)
            }
        }
        
        Log.d("BookManager", "Successfully copied ${copiedBooks.size} out of ${books.size} books")
        copiedBooks
    }
    
    /**
     * 复制文件
     */
    private fun copyFile(source: File, target: File) {
        FileInputStream(source).use { input ->
            FileOutputStream(target).use { output ->
                input.copyTo(output)
            }
        }
    }
    
    /**
     * 生成唯一的文件名
     */
    private fun generateUniqueFileName(originalName: String, directory: File): String {
        var fileName = originalName
        var counter = 1
        
        while (File(directory, fileName).exists()) {
            val nameWithoutExt = originalName.substringBeforeLast('.')
            val extension = originalName.substringAfterLast('.', "")
            fileName = if (extension.isNotEmpty()) {
                "${nameWithoutExt}_$counter.$extension"
            } else {
                "${nameWithoutExt}_$counter"
            }
            counter++
        }
        
        return fileName
    }
    
    /**
     * 计算文件哈希值用于去重
     */
    private fun getFileHash(file: File): String {
        return try {
            val md = MessageDigest.getInstance("MD5")
            FileInputStream(file).use { input ->
                val buffer = ByteArray(8192)
                var bytesRead: Int
                while (input.read(buffer).also { bytesRead = it } != -1) {
                    md.update(buffer, 0, bytesRead)
                }
            }
            md.digest().joinToString("") { "%02x".format(it) }
        } catch (e: Exception) {
            Log.e("BookManager", "Error calculating file hash for ${file.absolutePath}", e)
            file.absolutePath + file.length() // 降级方案
        }
    }
    
    /**
     * 检查文件是否为支持的格式
     */
    private fun isSupportedFile(file: File): Boolean {
        return FileFormatConfig.isSupportedFile(file.name) && file.length() > 0
    }
    
    /**
     * 从文件创建Book对象
     */
    private suspend fun createBookFromFile(file: File): Book {
        val fileName = file.nameWithoutExtension
        val bookId = UUID.randomUUID().toString()
        val format = getBookFormat(file.extension)
        
        val coverPath = try {
            coverExtractor.extractCover(file.absolutePath, format, bookId)
        } catch (e: Exception) {
            Log.w("BookManager", "Failed to extract cover for ${file.name}", e)
            null
        }
        
        return Book(
            id = bookId,
            title = getFileNameWithoutExtension(fileName),
            author = "未知作者",
            coverPath = coverPath,
            filePath = file.absolutePath,
            fileSize = file.length(),
            format = format,
            addTime = file.lastModified(),
            categories = emptyList(),
            description = null
        )
    }
    
    private fun getFileNameWithoutExtension(fileName: String): String {
        return fileName.replace(Regex("[_\\-]"), " ")
            .split(" ")
            .joinToString(" ") { word ->
                word.replaceFirstChar { 
                    if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() 
                }
            }
    }
    
    private fun getBookFormat(extension: String): com.esayread.data.BookFormat {
        return FileFormatConfig.getBookFormat(extension)
    }
    
    /**
     * 删除书籍及其关联数据
     */
    suspend fun deleteBook(book: Book): Boolean = withContext(Dispatchers.IO) {
        try {
            val file = File(book.filePath)
            
            // 删除物理文件
            val fileDeleted = if (file.exists()) {
                file.delete()
            } else {
                Log.w("BookManager", "File not found for deletion: ${book.filePath}")
                true // 文件不存在也算删除成功
            }
            
            if (fileDeleted) {
                // 清理关联数据（笔记、阅读进度等）
                clearBookRelatedData(book)
                // 清理路径记录
                pathManager.removeBookPath(book.id)
                Log.d("BookManager", "Successfully deleted book: ${book.title}")
                true
            } else {
                Log.e("BookManager", "Failed to delete file: ${book.filePath}")
                false
            }
        } catch (e: Exception) {
            Log.e("BookManager", "Error deleting book: ${book.title}", e)
            false
        }
    }
    
    /**
     * 清理书籍相关数据（笔记、阅读进度等）
     */
    private suspend fun clearBookRelatedData(book: Book) = withContext(Dispatchers.IO) {
        try {
            // 删除笔记文件（如果存在）
            val notesDir = File(context.filesDir, "notes")
            val noteFile = File(notesDir, "${book.id}.json")
            if (noteFile.exists()) {
                noteFile.delete()
                Log.d("BookManager", "Deleted notes for book: ${book.title}")
            }
            
            // 删除阅读进度文件（如果存在）
            val progressDir = File(context.filesDir, "progress")
            val progressFile = File(progressDir, "${book.id}.json")
            if (progressFile.exists()) {
                progressFile.delete()
                Log.d("BookManager", "Deleted reading progress for book: ${book.title}")
            }
            
            // 删除书签文件（如果存在）
            val bookmarksDir = File(context.filesDir, "bookmarks")
            val bookmarkFile = File(bookmarksDir, "${book.id}.json")
            if (bookmarkFile.exists()) {
                bookmarkFile.delete()
                Log.d("BookManager", "Deleted bookmarks for book: ${book.title}")
            }
            
            Log.d("BookManager", "Cleared all related data for book: ${book.title}")
        } catch (e: Exception) {
            Log.e("BookManager", "Error clearing book related data: ${book.title}", e)
        }
    }
}